<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // Promise的静态方法 => 构造函数Promise自己的方法
    // console.dir(Promise)

    // Promise.all()   Promise.all()方法用于将多个 Promise 实例，包装成一个新的 Promise 实例。
    // const p = Promise.all([p1, p2, p3]);
    // 上面代码中，Promise.all()方法接受一个数组作为参数，p1、p2、p3都是 Promise 实例，如果不是，就会先调用下面讲到的Promise.resolve方法，将参数转为 Promise 实例，
    // p的状态由p1、p2、p3决定，分成两种情况。

    // （1）只有p1、p2、p3的状态都变成fulfilled，p的状态才会变成fulfilled，此时p1、p2、p3的返回值组成一个数组，传递给p的回调函数。

    // （2）只要p1、p2、p3之中有一个被rejected，p的状态就变成rejected，此时第一个被reject的实例的返回值，会传递给p的回调函数。





    // Promise.race()


    // Promise.all() 处理多请求同时发送  => 按顺序返回结果,结果放到数组中

    // 链式写法
    /* var p1 = getNumAsync(1, 2000);  // 2s => {<fulfilled>:1}
    var p2 = getNumAsync(2, 1000);  // 1s => {<fulfilled>:2}
    var p3 = getNumAsync(3, 3000);  // 3s => {<fulfilled>:3}

    var list = [];
    p1.then(function (arg) {
        console.log("fulfilled", arg);
        list.push(arg);
        return p2;
    }).then(function (arg) {
        console.log("fulfilled", arg);
        list.push(arg);
        return p3;
    }).then(function (arg) {
        console.log("fulfilled", arg);
        list.push(arg);
        console.log("list",list);
    }).catch(function (err) {
        console.log("rejected", err);
    }) */


 

    // 模拟封装Promise.all();
    Promise.myAll = function (arr) { // 方法接收数组,数组中可以存放多个Promise实例  [p1,p2,p3]
        return new Promise(function (resolve, reject) {  // 返回新的Promise实例 => 等p1,p2,p3 全都成功就成功,有一个失败就失败 (异步)
            var list = [];
            var count = 0;   // 计数
            
            for (let i = 0; i < arr.length; i++) {
                let p = Promise.resolve(arr[i]); // 遍历得到数组中的每一个Promise实例  p1,p2,p3,4, 5
                // 给每一个Promise实例绑定成功时执行的回调函数 => 先变状态的先执行 
                p.then(arg => {
                    count ++;
                    // console.log("fulfilled", arg);

                    // list.push(arg);  // 先执行的先放到数组中 (不行)
                    list[i] = arg;  //  对应下标放到数组中
                    // console.log(i);

                    // console.log("list", list);

                    // 全都成功之后  将数据list 传递出局
                    if(count == arr.length){ // 三次都成功 => 新的Promise实例才会成功(将 p1 p2 p3的结果整合成数组传入)
                        resolve(list);
                    }
                    

                }).catch(err => {
                    console.log("rejected", err);
                    reject(err);  // 有一个失败 => 立即改为已失败状态
                })

            }
        })
    }


    /* for(let i=0;i<6;i++){
        setTimeout(()=>{
            console.log(i);
        },1000)
    } */


   /*  var p1 = getNumAsync(1, 2000);  // 2s => {<fulfilled>:1}
    var p2 = getNumAsync(2, 1000);  // 1s => {<fulfilled>:2}
    var p3 = getNumAsync(3, 3000);  // 3s => {<fulfilled>:3}

        
    var p = Promise.myAll([p1, p2, p3]);
    var p = Promise.all([p1, p2, p3]);

    p.then(function(list){
        console.log("全都成功",list);
    }).catch(function(err){
        console.log("rejected",err);
    }) */


    var p1 = getNumAsync(1, 2000);  // 2s => {<rejected>:1}
    var p2 = getNumAsync(2, 1000);  // 1s => {<fulfilled>:2}
    var p3 = getNumAsync(3, 3000);  // 3s => {<fulfilled>:3}
    // var p = Promise.myAll([p1, p2, p3]);
    var p = Promise.all([p1, p2, p3,4,5]);

    p.then(function(list){
        console.log("全都成功",list);
    }).catch(function(err){
        console.log("rejected",err);
    })






    function getNumAsync(num, delay = 0, isFulfilled = true) {
        var p = new Promise(function (resolve, reject) {
            // 回调函数 -> 容器 -> 用来存放异步操作 (根据异步操作的结果改变状态)
            setTimeout(() => {
                isFulfilled ? resolve(num) : reject(num); // {<fulfilled>:1}
                // console.log(p);
            }, delay);
        })
        return p;  // {<pending>:undefined}
    }



</script>

</html>